package realizeBockingQueue;

/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: lishuo
 * Date: 2023-04-02
 * Time: 10:57
 */
public class MyBlockingQueue {
    private int[] items = new int[1000];
    // 约定 [head, tail) 队列 的有效元素
    volatile private int head = 0;
    volatile private int tail = 0;
    volatile private  int size = 0;

    // 入队列
    synchronized public void put(int value) throws InterruptedException {
        // Java官方是不建议使用wait的，因为wait时有可能被其他方法（如interrupt）给中断的
        // 此时wait等待的条件还未成熟就被提前唤醒了，继续向下执行就可能出现各种问题。因此较
        // 稳妥的办法是，将if替换为while，这样就可以保证，即使提前中断还是会在判断一下是否满足条件。
        while (size == items.length) {
            // 队列满，插入失败
            //return;
            this.wait();
        }
        // 插入元素
        items[tail] = value;
        tail++;
        // 判断 tail 大小，如果 tail 达到末尾，需要从头再来
        if (tail == items.length) {
            tail = 0;
        }
        size++;
        this.notify();
    }

    //出队列
    synchronized public int take() throws InterruptedException {
        // 这里同上
        while (size == 0) {
            // 队列为空，取元素失败
            this.wait();
        }
        // 取元素
        int value = items[head];
        head++;
        // 如果 head 达到末尾，需要从头再来
        if (head == items.length) {
            head = 0;
        }
        size--;
        this.notify();
        return value;
    }

}
